package com.health.config;

import com.alibaba.fastjson.JSON;
import com.health.entity.Result;
import com.health.filter.UserAuthenticationFilter;
import com.health.provider.UserLoginAuthenticationProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.servlet.http.HttpServletResponse;

/**
 * @Classname SecurityConfig
 * @Description TODO
 * @Version 1.0.0
 * @Date 2023/3/21 17:07
 * @Author RainGrd
 */
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserLoginAuthenticationProvider loginAuthenticationProvider;

    /**
     * 用户认证
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //使用自定义的Provider，进行数据校验
        auth.authenticationProvider(loginAuthenticationProvider);
    }

    /**
     * 解决无法直接注入 AuthenticationManager
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    /**
     * 自定义成功回调、失败回调、登陆url地址等
     * <p>
     * 可以在自定义UserAuthenticationFilter里面直接重写对应方法，
     * 例 成功回调：
     *
     * @return
     * @throws Exception
     * @Override public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
     * super.setAuthenticationSuccessHandler(successHandler);
     * }
     */
    @Bean
    public UserAuthenticationFilter userAuthenticationFilter() throws Exception {
        UserAuthenticationFilter filter = new UserAuthenticationFilter();
        //设置验证成功后的回调
        filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            log.info("用户认证成功");
            //响应成功状态码必须为200
            response.setStatus(HttpServletResponse.SC_OK);
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding("utf-8");
            //将数据以json的形式返回给前台
            response.getWriter().print(JSON.toJSONString(Result.success()));
        });
        //设置验证失败后的回调
        filter.setAuthenticationFailureHandler((request, response, exception) -> {
            log.info("用户认证失败----{}", exception.getMessage());
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding("utf-8");
            //将数据以json的形式返回给前台
            response.getWriter().print(JSON.toJSONString(Result.error(exception.getMessage())));
        });
        //设置用户发起登陆请求时的url
        filter.setFilterProcessesUrl("/login.do");
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    }
}
